/**
 * @RedisPoolStaticticsMBean.java  COPYRIGHT xiaojian
 * 
 * Created on 2019年7月29日 下午5:11:43
 */
package xj.toolkit.redis;

import java.util.List;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.ReflectionException;

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;

/**
 * @author <a href="mailto:cxj2000@gmail.com">xiaojian.cao</a>
 *
 */
public class RedisPoolStaticticsMBean  implements DynamicMBean {
	
	private static final Logger logger = LoggerFactory.getLogger(RedisPoolStaticticsMBean.class);

	GenericObjectPool pool = null;
	
	public RedisPoolStaticticsMBean(GenericObjectPool pool) {
		this.pool = pool;
	}

	public Object getAttribute(String attribute)
			throws AttributeNotFoundException, MBeanException, ReflectionException {
		if (pool == null) {
			return null;
		}

		if (attribute.equals("maxTotal")) {
			return pool.getMaxTotal();
		}

		if (attribute.equals("maxIdle")) {
			return pool.getMaxIdle();
		}

		if (attribute.equals("maxWaitMillis")) {
			return pool.getMaxWaitMillis();
		}

		if (attribute.equals("minIdle")) {
			return pool.getMinIdle();
		}

		if (attribute.equals("numActive")) {
			return pool.getNumActive();
		}

		if (attribute.equals("numIdle")) {
			return pool.getNumIdle();
		}

		return null;
	}

	/**
	 * 
	 * @see javax.management.DynamicMBean#setAttribute(javax.management.Attribute
	 *      )
	 */
	public void setAttribute(Attribute attribute)
			throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {

	}

	/**
	 * 
	 * @see javax.management.DynamicMBean#getAttributes(java.lang.String[])
	 */
	public AttributeList getAttributes(String[] attributes) {
		Preconditions.checkArgument(attributes != null && attributes.length > 0);
		AttributeList al = new AttributeList();
		for (String attribute : attributes) {
			Object value = null;
			try {
				value = this.getAttribute(attribute);
			} catch (Exception e) {
				logger.error("Cannot get attribute[" + attribute + "] value.", e);
				continue;
			}
			al.add(new Attribute(attribute, value));
		}
		return al;
	}

	/**
	 * 
	 * @see javax.management.DynamicMBean#setAttributes(javax.management.
	 *      AttributeList)
	 */
	public AttributeList setAttributes(AttributeList attributes) {
		return null;
	}

	/**
	 * 
	 * @see javax.management.DynamicMBean#invoke(java.lang.String,
	 *      java.lang.Object[], java.lang.String[])
	 */
	public Object invoke(String actionName, Object[] params, String[] signature)
			throws MBeanException, ReflectionException {
		return null;
	}

	/**
	 * 
	 * @see javax.management.DynamicMBean#getMBeanInfo()
	 */
	public MBeanInfo getMBeanInfo() {
		List<MBeanAttributeInfo> infoLists = Lists.newArrayList();
		infoLists.add(new MBeanAttributeInfo("maxTotal", "java.lang.Integer", null, true, false, false));
		infoLists.add(new MBeanAttributeInfo("maxIdle", "java.lang.Integer", null, true, false, false));
		infoLists.add(new MBeanAttributeInfo("maxWaitMillis", "java.lang.Long", null, true, false, false));
		infoLists.add(new MBeanAttributeInfo("minIdle", "java.lang.Integer", null, true, false, false));
		infoLists.add(new MBeanAttributeInfo("numActive", "java.lang.Integer", null, true, false, false));
		infoLists.add(new MBeanAttributeInfo("numIdle", "java.lang.Integer", null, true, false, false));

		List<MBeanConstructorInfo> constructorInfos = Lists.newArrayList();
		constructorInfos.add(new MBeanConstructorInfo("RedisPoolStaticticsMBean()", null, null));

		return new MBeanInfo("RedisPoolStatictics", null,
				(MBeanAttributeInfo[]) infoLists.toArray(new MBeanAttributeInfo[infoLists.size()]),
				(MBeanConstructorInfo[]) constructorInfos
						.toArray(new MBeanConstructorInfo[constructorInfos.size()]),
				null, null);
	}

}
